local cjson = require("cjson");
function class(classname, super)
    local superType = type(super)
    local cls
    if superType ~= "function" and superType ~= "table" then
        superType = nil
        super = nil
    end
    if superType == "function" or (super and super.__ctype == 1) then
        cls = {}
        if superType == "table" then
            for k,v in pairs(super) do cls[k] = v end
            cls.__create = super.__create
            cls.super    = super
        else
            cls.__create = super
            cls.ctor = function() end
        end
        cls.__cname = classname
        cls.__ctype = 1
        function cls.new(...)
            local instance = cls.__create(...)
            for k,v in pairs(cls) do instance[k] = v end
            instance.class = cls
            instance:ctor(...)
            return instance
        end
    else
        if super then
            cls = {}
            setmetatable(cls, {__index = super})
            cls.super = super
        else
            cls = {ctor = function() end}
        end
        cls.__cname = classname
        cls.__ctype = 2
        cls.__index = cls
        function cls.new(...)
            local instance = setmetatable({}, cls)
            instance.class = cls
            instance:ctor(...)
            return instance
        end
    end
    return cls
end

function handler(obj, method)
    return function(...)
        return method(obj, ...)
    end
end

local UpdateScene = class("UpdateScene", function()
    local scene = cc.Scene:create();
    return scene;
end)

function UpdateScene:ctor()
    local writePath = cc.FileUtils:getInstance():getWritablePath();
    local target = cc.Application:getInstance():getTargetPlatform()
    if target == 0 then
        writePath = string.gsub(writePath, '\\', '/');
    end
    self.updFolder = writePath .. "upd/";
    local visibleRect = cc.Director:getInstance():getOpenGLView():getVisibleRect();
    local bg = cc.Sprite:create("png/launch_bg.png");
    bg:setPosition({x = visibleRect.x + visibleRect.width/2,y = visibleRect.y + visibleRect.height/2});
    self:addChild(bg);

    local node = cc.Node:create();
    node:setPosition({x = visibleRect.x + visibleRect.width/2,y = visibleRect.y + 100})
    self:addChild(node);

    local timerBg = cc.Sprite:create("png/loading_line_border.png");
    node:addChild(timerBg);
    local timer = cc.ProgressTimer:create(cc.Sprite:create("png/loading_line.png"));
    timer:setPercentage(0);
    timer:setBarChangeRate({x = 1,y = 0});
    timer:setType(1);
    timer:setMidpoint({x = 0,y = 0.5});
    node:addChild(timer);
    self.progressTimer = timer;
    local text = cc.Label:createWithSystemFont("", "fonts/Arial.ttf", 32);
    text:setString("更新中...请稍后")
    node:addChild(text);
    text:setPosition({x = 0,y = -50});
    self.text = text;
    local platform = self:getSysInfo()
    local url = self:getHttpUrl({api="update",params={platform=platform}})
    self:httpGet(url,handler(self,self.requestInfo));
end


function UpdateScene:requestInfo(resp)
    print(resp)
    print(type(resp))
    resp = cjson.decode(resp)
    print(type(resp))
    local downurl = resp.url .. "/test.txt"
    self:httpGet(downurl,handler(self,self.secondStepCbk))
    --test
    --self:notNeedUpdate();
    --[[
    resp = resp.d;
    self.apUrl = resp.url;
    self.idkey = resp.idkey;
    self.ps = resp.ps;
    local curVersion = self:getCurVersion();
    local sys = self:getSys();
    local m = {ver = curVersion,sys = sys,mid = 36};
    m = cjson.encode(m);
    self:post({cbk = handler(self,self.secondStepCbk),url = self.apUrl,params = {{key = "id",value = "0"},{key = "v",value = "json"},{key = "m",value = m}}});
    --]]
end

function UpdateScene:secondStepCbk(resp)
    print(resp)
    --dump(resp);
    -- local data = resp[1];
    -- if data.s == 0 then
    --     local d = data.d;
    --     local res = d.res;
    --     local serverVersion = res.ver;
    --     local curVersion = self:getCurVersion();
    --     self.vir = d.vir;
    --     if serverVersion ~= curVersion then
    --         self.text:setString("更新中,请稍后");
    --         self:updateRes(res);
    --     else
    --         local m = {ps = self.ps,id = 1,mid = 35};
    --         m = cjson.encode(m);
    --         self:post({cbk = handler(self,self.thirdStepCbk),url = self.apUrl,params = {{key = "id",value = "0"},{key = "v",value = "json"},{key = "m",value = m}}});
    --     end
    -- else
    --     self.text:setString("服务器出错");
    -- end
end



function UpdateScene:thirdStepCbk(resp)
    dump(resp,"thirdStepCbk",10);
    if resp[1].s == 0 then
        self.ps = resp[1].d.ps;
        self:notNeedUpdate();
    else
        --test
        self:notNeedUpdate();
    end
end


function UpdateScene:bigVersionUpdate()
    self:clean_dir(self.updFolder);
end

function UpdateScene:diffTable(oldTable,newTable)
    local reTable = {};
    for key, newFile in pairs(newTable) do
		local oldFile = oldTable[key];
        if oldFile then
			if newFile.crc == oldFile.crc and newFile.size == oldFile.size then
				--same file
			else
				reTable[key] = newFile;
			end
		else
			--new file
			reTable[key] = newFile;
		end
    end
    return reTable;
end



function UpdateScene:write_content_to_file(path,content,mode)
    mode = mode or "w+b"
    local file = io.open(path, mode)
    if file then
        local hr,err = file:write(content)
        if hr == nil then
            print(err)
            return false
        end
        io.close(file)
        return true
    else
        print("can't open file:"..path)
        return false
    end
end

function UpdateScene:is_file_exists(path)
    return cc.FileUtils:getInstance():isFileExist(path)
end

function UpdateScene:clean_dir(path)
    local ret = cc.FileUtils:getInstance():removeDirectory(path)
    print("remove_dir",path,ret)
end

function UpdateScene:make_dir(path)
    local ret = cc.FileUtils:getInstance():createDirectory(path)
    print("make_dir",path,ret)
    return ret
end

function UpdateScene:write_file(path,content)
    self:make_dir(path)
    self:write_content_to_file(path,content)
end

function UpdateScene:lua_do_string(str)
    local fn = assert(loadstring(str));
    return fn();
end


function UpdateScene:getCurVersion()
    local curVersion = "0.1.1.1";
    return curVersion;
end

function UpdateScene:getHttpUrl(args)
    local signkey = '96e79218965eb72c92a549dd5a330112'
    local param = cjson.encode(args.params or {})
    local sign = crypto.md5(args.api .. "&" .. param .. "&" .. signkey)
    local url = "http://114.67.229.15:8081/client?method=".. args.api .. "&sign=" .. sign .. "&param=" .. string.urlencode(param);
    return url
end


function UpdateScene:httpGet(url,cbk)
    local function requestGetCbk(event)
        local requestBack = event.request;
        if event.name ~= "completed" then
            return; 
        end
        local code = requestBack:getResponseStatusCode()
        if code ~= 200 then
            print("code ", code)
            return; 
        end
        local resp = requestBack:getResponseString()
        if cbk then
            cbk(resp);
        end
    end
    local request = network.createHTTPRequest(requestGetCbk,url,"GET");
    request:setTimeout(30);
    request:start();
end


function UpdateScene:getSysInfo()
    local sys = "";
    local target = cc.Application:getInstance():getTargetPlatform()
    if target == 3 then
        sys = "android";
    elseif target == 4 or target == 5 then
        sys = "ios";
    else 
        sys = "pc";
    end
    return sys;
end

function UpdateScene:updateRes(res)
    local url = res.url;
    local serverVersion = res.ver;
    print(res);
    --dump(res);
end

function UpdateScene:notNeedUpdate()
    self.text:setString("当前版本为最新版本");
    local pro = cc.ProgressFromTo:create(1,0,100);
    local cbk = cc.CallFunc:create(function()
        require("config")
        require("cocos.init")
        require("framework.init")
        cc.Director:getInstance():replaceScene(require(SCRIPTS_DIR .. ".scenes.MainScene").new());
    end);
    self.progressTimer:runAction(cc.Sequence:create(pro,cbk));
end

return UpdateScene;